<!-- 地图路线规划弹窗 -->
<template>
  <div v-if="modelValue" class="fixed inset-0 z-[9999] overflow-y-auto">
    <div class="flex items-center justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:block sm:p-0">
      <!-- 背景遮罩 -->
      <div 
        class="fixed inset-0 transition-opacity bg-gray-500 bg-opacity-75" 
        @click="$emit('update:modelValue', false)"
      ></div>

      <!-- 弹窗内容 -->
      <div class="inline-block w-full max-w-4xl p-6 my-8 overflow-hidden text-left align-middle transition-all transform bg-white shadow-xl rounded-2xl relative">
        <!-- 加载状态遮罩 -->
        <div v-if="mapState.isLoading" 
          class="absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 rounded-2xl">
          <div class="text-white flex items-center">
            <i class="fas fa-spinner fa-spin mr-2"></i>
            正在加载...
          </div>
        </div>

        <!-- 头部 -->
        <div class="flex justify-between items-start mb-6">
          <h2 class="text-2xl font-bold text-gray-900">路线规划</h2>
          <button 
            @click="$emit('update:modelValue', false)"
            class="text-gray-400 hover:text-gray-500"
          >
            <font-awesome-icon icon="times" class="text-xl" />
          </button>
        </div>

        <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
          <!-- 左侧输入面板 -->
          <div class="space-y-4">
            <div class="bg-gray-50 p-4 rounded-lg">
              <div class="space-y-3">
                <!-- 起点选择 -->
                <div>
                  <label class="block text-sm font-medium text-gray-700 mb-1">起点</label>
                  <select
                    v-model="startPoint"
                    class="w-full px-4 py-2 border rounded-lg mb-2 bg-white"
                  >
                    <option value="">选择常用位置</option>
                    <option v-for="loc in COMMON_LOCATIONS" :key="loc" :value="loc">{{ loc }}</option>
                  </select>
                  <input
                    v-model="startPoint"
                    type="text"
                    placeholder="输入起点位置"
                    class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500"
                  >
                </div>

                <!-- 终点选择 -->
                <div>
                  <label class="block text-sm font-medium text-gray-700 mb-1">终点</label>
                  <input
                    v-model="endPoint"
                    type="text"
                    :placeholder="destination || '输入终点位置'"
                    class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500"
                  >
                </div>

                <!-- 出行方式选择 -->
                <div class="flex space-x-2">
                  <button
                    v-for="mode in TRAVEL_MODES"
                    :key="mode.value"
                    @click="selectedMode = mode.value"
                    :class="[
                      'flex-1 px-4 py-2 rounded-lg transition-colors',
                      selectedMode === mode.value 
                        ? 'bg-blue-600 text-white' 
                        : 'bg-gray-100 hover:bg-gray-200'
                    ]"
                  >
                    {{ mode.label }}
                  </button>
                </div>

                <button
                  @click="debouncedPlanRoute"
                  class="w-full bg-blue-600 text-white py-3 rounded-lg transition-all"
                  :class="{'opacity-50 cursor-not-allowed': !startPoint || !endPoint || mapState.isLoading}"
                  :disabled="!startPoint || !endPoint || mapState.isLoading"
                >
                  {{ mapState.isLoading ? '规划中...' : '开始规划路线' }}
                </button>
              </div>
            </div>
          </div>

          <!-- 右侧地图容器 -->
          <div class="md:col-span-2">
            <div ref="mapContainer" class="h-[400px] rounded-lg overflow-hidden map-container"></div>
            <div ref="routePanel" class="mt-4 bg-white p-4 rounded-lg shadow-md max-h-64 overflow-y-auto route-panel"></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch, onBeforeUnmount, shallowRef, nextTick } from 'vue'
import AMapLoader from '@amap/amap-jsapi-loader'
import { ElMessage } from 'element-plus'

// 解决地图加载失败的问题
AMapLoader.reset()

// 常量定义
const MAP_CONFIG = {
  KEY: '512cb9e9902a4d511b7abfc6f55d5ac9',
  VERSION: '2.0',
  DEFAULT_CENTER: [107.170731, 34.364089],
  DEFAULT_ZOOM: 13
}

const COMMON_LOCATIONS = [
  '宝鸡火车站',
  '宝鸡南站',
  '市政府',
  '陈仓老街',
  '人民公园'
]

const TRAVEL_MODES = [
  { label: '驾车', value: 'driving' },
  { label: '步行', value: 'walking' },
  { label: '公交', value: 'transit' }
]

// Props 定义
const props = defineProps<{
  modelValue: boolean
  destination?: string
  position?: [number, number]
}>()

const emit = defineEmits<{
  (e: 'update:modelValue', value: boolean): void
}>()

// 状态管理
const startPoint = ref('')
const endPoint = ref(props.destination || '')
const selectedMode = ref('driving')
const mapContainer = ref<HTMLElement | null>(null)
const routePanel = ref<HTMLElement | null>(null)

// 使用 shallowRef 优化大对象的响应式
const mapState = shallowRef({
  map: null as any,
  routePlanner: null as any,
  isLoading: false
})

// 缓存 AMap 实例
let AMapInstance: any = null

// 防抖函数
const useDebounce = (fn: Function, delay: number) => {
  let timer: NodeJS.Timeout | null = null
  return (...args: any[]) => {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      fn.apply(null, args)
    }, delay)
  }
}

// 错误处理
const handleError = (error: any, context: string) => {
  const errorMap = new Map([
    ['MAP_LOAD', '地图加载失败，请检查网络连接'],
    ['ROUTE_PLAN', '路线规划失败，请稍后重试'],
    ['LOCATION_NOT_FOUND', '无法找到指定位置，请检查输入']
  ])

  const message = errorMap.get(context) || '操作失败，请重试'
  ElMessage.error(message)
  console.error(`${context}错误:`, error)
}

// 优化地图加载函数
const loadAMap = async (plugins: string[] = []) => {
  if (AMapInstance) return AMapInstance

  try {
    AMapInstance = await AMapLoader.load({
      key: MAP_CONFIG.KEY,
      version: MAP_CONFIG.VERSION,
      plugins: [...new Set([...MAP_CONFIG.PLUGINS.BASIC, ...plugins])]
    })
    return AMapInstance
  } catch (error) {
    handleError(error, 'MAP_LOAD')
    throw error
  }
}

// 初始化地图
const initMap = async () => {
  if (!mapContainer.value) return

  try {
    window.AMap = await AMapLoader.load({
      key: MAP_CONFIG.KEY,
      version: MAP_CONFIG.VERSION,
      plugins: ['AMap.Scale', 'AMap.ToolBar', 'AMap.Driving', 'AMap.Walking', 'AMap.Transfer']
    })

    if (mapState.value.map) {
      mapState.value.map.destroy()
    }

    mapState.value.map = new window.AMap.Map(mapContainer.value, {
      zoom: MAP_CONFIG.DEFAULT_ZOOM,
      center: props.position || MAP_CONFIG.DEFAULT_CENTER
    })

    // 添加控件
    mapState.value.map.addControl(new window.AMap.Scale())
    mapState.value.map.addControl(new window.AMap.ToolBar())

    // 如果有目标位置，添加标记
    if (props.position) {
      new window.AMap.Marker({
        position: [props.position[1], props.position[0]],
        map: mapState.value.map
      })
    }

  } catch (error) {
    console.error('地图加载失败:', error)
    ElMessage.error('地图加载失败，请刷新页面重试')
  }
}

// 路线规划函数
const planRoute = async () => {
  if (!mapState.value.map || !startPoint.value || !endPoint.value) return
  
  mapState.value.isLoading = true
  
  try {
    // 清理现有路线
    if (mapState.value.routePlanner) {
      mapState.value.routePlanner.clear()
      mapState.value.routePlanner = null
    }

    // 创建路线规划实例
    let routePlannerConstructor
    switch (selectedMode.value) {
      case 'driving':
        routePlannerConstructor = window.AMap.Driving
        break
      case 'walking':
        routePlannerConstructor = window.AMap.Walking
        break
      case 'transit':
        routePlannerConstructor = window.AMap.Transfer
        break
      default:
        throw new Error('不支持的出行方式')
    }

    // 创建路线规划实例
    mapState.value.routePlanner = new routePlannerConstructor({
      map: mapState.value.map,
      panel: routePanel.value,
      policy: selectedMode.value === 'driving' ? 0 : undefined,
      autoFitView: true
    })

    // 执行路线规划
    mapState.value.routePlanner.search(
      startPoint.value,
      endPoint.value,
      function(status: string, result: any) {
        if (status === 'complete') {
          ElMessage.success('路线规划成功')
        } else {
          ElMessage.error('路线规划失败：' + result)
        }
        mapState.value.isLoading = false
      }
    )

  } catch (error: any) {
    console.error('路线规划失败:', error)
    ElMessage.error(error.message || '路线规划失败，请稍后重试')
    mapState.value.isLoading = false
  }
}

// 防抖处理的路线规划
const debouncedPlanRoute = useDebounce(planRoute, 300)

// 监听目的地变化
watch(() => props.destination, (newVal) => {
  if (newVal) {
    endPoint.value = newVal
  }
})

// 监听弹窗显示状态
watch(() => props.modelValue, (newVal) => {
  if (newVal) {
    // 设置终点
    if (props.destination) {
      endPoint.value = props.destination
    }
    // 延迟初始化地图，确保容器已经渲染
    nextTick(() => {
      initMap()
    })
  }
})

// 组件生命周期
onMounted(() => {
  if (props.modelValue) {
    initMap()
  }
})

onBeforeUnmount(() => {
  if (mapState.value.routePlanner) {
    mapState.value.routePlanner.clear()
    mapState.value.routePlanner = null
  }
  if (mapState.value.map) {
    mapState.value.map.destroy()
    mapState.value.map = null
  }
})
</script>

<style scoped>
:root {
  --primary-color: #3b82f6;
  --hover-color: #2563eb;
}

.transition-all {
  will-change: transform, opacity;
}

:deep(.amap-container) {
  z-index: 1 !important;
}

:deep(.amap-lib-driving) {
  border-radius: 8px;
  padding: 12px;
}

.route-panel {
  scrollbar-width: thin;
  scrollbar-color: #888 #f1f1f1;
  -webkit-overflow-scrolling: touch;
  scroll-behavior: smooth;
}

.route-panel::-webkit-scrollbar {
  width: 6px;
}

.route-panel::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

.route-panel::-webkit-scrollbar-thumb {
  background: #888;
  border-radius: 3px;
}

.route-panel::-webkit-scrollbar-thumb:hover {
  background: #666;
}

.map-container {
  transform: translateZ(0);
  backface-visibility: hidden;
}
</style> 